package com.company;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;

import com.company.LambdaDemo.Student;
import com.company.Thread.TestDto;
import com.company.Thread.UserInfo;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

public class Main {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Student student = new Student(1, null);

        Field field = student.getClass().getDeclaredField("name");
        if (Objects.nonNull(field)) {
            field.setAccessible(true);
            field.set(student, null);
        }

        int index = 1;
        System.out.println(index++);
        System.out.println(index);

        System.out.println(++index);
        System.out.println(index);

        List<TestDto> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            TestDto model = new TestDto();
            model.setSex(RandomUtil.randomInt());
            model.setAge(RandomUtil.randomInt());
            model.setName(RandomUtil.randomString(10));
            list.add(model);
        }
        String jsonStr = JSONUtil.toJsonStr(list.get(0));
        JSONObject test = JSONUtil.parseObj(JSONUtil.toJsonStr(list.get(0)));

        StopWatch stopWatch = new StopWatch("测试性能");
        stopWatch.start("开始测试");
        for (int i = 0; i < 1000000; i++) {
            // list.forEach(item -> {
            // String sex = getPoolValue(item, "sex");
            // String age = getPoolValue(item, "age");
            // String name = getPoolValue(item, "name");
            // });

            list.forEach(item -> {
                JSONObject obj = JSONUtil.parseObj(JSONUtil.toJsonStr(item));
                // String sex = obj.getStr("sex");
                // String age = obj.getStr("age");
                // String name = obj.getStr("name");
                System.out.println(obj);
            });
        }

        stopWatch.stop();
        System.out.println(stopWatch.prettyPrint());
    }

    private static String getPoolValue(UserInfo model, String fieldName) {
        try {
            Field field = model.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            Object value = field.get(model);
            if (Objects.nonNull(value)) {
                return value.toString();
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            System.out.println(e.getMessage());
        }
        return StrUtil.EMPTY;
    }

    static void test() {
        DateTime dateTime = DateUtil.parse("2021-1-1", DatePattern.NORM_DATE_FORMAT);

        String numb = StrUtil.format("{}{}{}{}.{}", Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE,
            Long.MAX_VALUE);
        System.out.println();
        boolean number = NumberUtil.isNumber(numb);
        BigDecimal input = new BigDecimal(numb);
        BigDecimal[] parts = input.divideAndRemainder(BigDecimal.ONE);
        System.out.println(Arrays.toString(parts));
        System.out.println(new BigDecimal(Long.MAX_VALUE));
        System.out.println(Long.MAX_VALUE);
        UserInfo user = new UserInfo();
        user.setSex(145);
        changeUser(user);
        System.out.println(user);

        boolean isMatch = Pattern.matches("^(-?\\d+)(\\.\\d+)?$", "_12321414");
        System.out.println("字符串中是否包含了数字 " + isMatch);
    }

    static int testChinese1(String str) {
        int count = 0;
        char[] c = str.toCharArray();
        for (char value : c) {
            String len = Integer.toBinaryString(value);
            if (len.length() > 8) {
                count++;
            }
        }
        return count;
    }

    static int testChinese3(String str) {
        int count = 0;
        String regEx = "[\u4e00-\u9fa5]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        while (m.find()) {
            count++;
        }
        return count;
    }

    static void changeUser(UserInfo user) {
        user = new UserInfo();
        user.setSex(44);
    }

    static void changeHashMap(HashMap map) {

        map = new HashMap<Integer, String>();

        map.put(1, "163");

    }

    static String testFinally(int num) {
        try {
            num = 10 / num;
            return "成功";
        } catch (Exception e) {

        } finally {
            System.out.println("finally");
        }
        return "错误";
    }

    // public static void main(String[] args) throws InterruptedException {
    // ArrayList<String> l1 = new ArrayList<>();
    //
    // ArrayList<Integer> l2 = new ArrayList<>();
    //
    // l1.add("1");
    //
    // l2.add(1);
    //
    // System.out.println(l1.get(0).getClass());
    //
    // System.out.println(l2.get(0).getClass());
    //
    // System.out.println(l1.getClass() == l2.getClass());
    // // for (int i = 0; i < 20; i++) {
    // // new Thread(() -> {
    // // while (true) {
    // // new Random().nextInt(100);
    // // }
    // // }, "high-cpu" + i).start();
    // // }
    //
    // Thread.sleep(600000);
    // System.out.println(18 & 7);
    //
    // System.out.println(18 | 7);
    //
    // int h;
    //
    // Object obj = new Object();
    // System.out.println(StrUtil.format("十进制：{}、二进制：{}", obj.hashCode(), Integer.toBinaryString(obj.hashCode())));
    // System.out.println(
    // StrUtil.format("十进制：{}、二进制：{}", obj.hashCode() >>> 16, Integer.toBinaryString(obj.hashCode() >>> 16)));
    // System.out.println(StrUtil.format("十进制：{}、二进制：{}", (h = obj.hashCode()) ^ (h >>> 16),
    // Integer.toBinaryString((h = obj.hashCode()) ^ (h >>> 16))));
    //
    // System.out.println(testFinally(11));
    //
    // String dateStr1 = "2017-04-01 22:36:00";
    // Date date1 = DateUtil.parse(dateStr1);
    //
    // String dateStr2 = "2020-07-24 14:40:23";
    // Date date2 = DateUtil.parse(dateStr2);
    //
    // System.out.println(DateUtil.between(DateUtil.date(), date2, DateUnit.MINUTE, false));
    //
    // UserInfo user = new UserInfo();
    // user.setSex(5);
    //
    // System.out.println(user.getSex());
    //
    // List<Integer> list = Stream.of(1, 2, 3, 4, 5, 5, 5).collect(Collectors.toList());
    // List<Integer> reList = new ArrayList<>();
    // reList.add(4);
    // reList.add(5);
    // reList.add(8);
    // reList.add(7);
    // list.removeIf(a -> a.equals(5));
    // System.out.println(list);
    //
    // Thread.sleep(30000);
    // System.out.println(DateUtil.date());
    // System.exit(0);
    // }

    static void testHashmap() {
        HashMap<String, Integer> hashMap = new HashMap<>();
        String key = "key";
        hashMap.put(key, 0);
        // 测试线程安全，程序结束查看redis中count的值是否为1000
        ExecutorService executorService = Executors.newFixedThreadPool(1000);
        IntStream.range(0, 1000).forEach(i -> executorService.execute(() -> {
            hashMap.put(key, hashMap.get(key) + 1);
        }));
        System.out.println("hashmap的值：" + hashMap.get(key));
    }

    static void testConcurrentHashMap() {
        ConcurrentHashMap<String, Integer> hashMap = new ConcurrentHashMap<>();
        String key = "key";
        hashMap.put(key, 0);
        // 测试线程安全，程序结束查看redis中count的值是否为1000
        ExecutorService executorService = Executors.newFixedThreadPool(1000);
        IntStream.range(0, 1000).parallel().forEach(i -> executorService.execute(() -> {
            hashMap.put(key, hashMap.get(key) + 1);
        }));
        System.out.println("ConcurrentHashMap的值：" + hashMap.get(key));
    }

    public static void threadTest(int num, Consumer<Integer> consumer) {
        ExecutorService executorService = Executors.newFixedThreadPool(num);

        IntStream.range(0, num * 2).forEach(item -> {
            executorService.execute(() -> {
                consumer.accept(item);
            });
        });
    }
}
